package com.manage.function.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

/**
 *  @author jinghj
 *  @date 2025/3/29
 *  关闭占用端口进程
 *  执行后会提示输入要释放的端口号，然后执行端口释放操作，并输出执行结果。
 */
public class PortKiller {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入要释放的端口号：");
        int port = scanner.nextInt();

        try {
            killProcessByPort(port);
            System.out.println("端口释放操作执行完成");
        } catch (Exception e) {
            System.err.println("操作失败: " + e.getMessage());
        } finally {
            scanner.close();
        }
    }

    private static void killProcessByPort(int port) throws IOException, InterruptedException {
        String os = System.getProperty("os.name").toLowerCase();

        if (os.contains("win")) {
            handleWindowsPort(port);
        } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
            handleUnixPort(port);
        } else {
            throw new UnsupportedOperationException("不支持的操作系统");
        }
    }

    private static void handleWindowsPort(int port) throws IOException, InterruptedException {
        // 获取进程PID
        Process netstatProcess = Runtime.getRuntime().exec(
                new String[]{"cmd", "/c", "netstat -ano | findstr :" + port});

        String output = readProcessOutput(netstatProcess);
        if (output.isEmpty()) {
            throw new RuntimeException("未找到占用端口" + port + "的进程");
        }

        // 提取最后一个出现的PID（最新的连接）
        String[] lines = output.split("\n");
        String lastLine = lines[lines.length - 1].trim();
        String pid = lastLine.split("\\s+")[4];

        // 终止进程
        Process killProcess = Runtime.getRuntime().exec(
                new String[]{"cmd", "/c", "taskkill /PID " + pid + " /F"});
        if (killProcess.waitFor() != 0) {
            throw new RuntimeException("终止进程失败，可能需要管理员权限");
        }
        System.out.println("成功终止进程 PID: " + pid);
    }

    private static void handleUnixPort(int port) throws IOException, InterruptedException {
        // 获取进程PID
        Process lsofProcess = Runtime.getRuntime().exec(
                new String[]{"sh", "-c", "lsof -t -i :" + port});

        String pid = readProcessOutput(lsofProcess).trim();
        if (pid.isEmpty()) {
            throw new RuntimeException("未找到占用端口" + port + "的进程");
        }

        // 终止进程
        Process killProcess = Runtime.getRuntime().exec(
                new String[]{"sh", "-c", "kill -9 " + pid});
        if (killProcess.waitFor() != 0) {
            throw new RuntimeException("终止进程失败，可能需要sudo权限");
        }
        System.out.println("成功终止进程 PID: " + pid);
    }

    private static String readProcessOutput(Process process) throws IOException {
        StringBuilder output = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
            }
        }
        return output.toString().trim();
    }
}
